package com.company.project.search.engine;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.company.project.search.entity.Search;
import com.company.project.search.service.SearchEsService;
import com.company.project.search.util.OkHttpUtil;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * 易阅通
 * https://www.cnpereading.com/result
 */
@Component
public final class E4 extends AbstractE implements Callback {

    private static final String href = "https://www.cnpereading.com/bookDetail/";
    private static final String url = "https://www.cnpereading.com/api/search/title?_t=0.01613214436094057&i18n=zhCN";

    @Resource
    private SearchEsService searchEsService;

    private static final Headers headers = new Headers.Builder()
            .add("Referer", "https://kns.cnki.net/kns8/defaultresult/index")
            .add("Accept", "application/json, text/plain, */*")
            .add("Content-Type", "application/x-www-form-urlencoded")
            .add("Cache-Control", "no-cache")
            .add("Connection", "keep-alive")
            .add("Origin", "https://www.cnpereading.com")
            .add("X-Requested-With", "XMLHttpRequest")
            .add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36")
            .build();

    @Override
    public void search(Param p) {
        p.engine = Engine.ID_E4;

        RequestBody body = new FormBody.Builder()
                .add("keyword", p.keyword)
                .add("currentPage", String.valueOf(p.curPage))
                .add("perPageRows", "20")
                .add("orderName", "correlation")
                .add("order", "DESC")
                .add("catalog", "ALL")
                .add("onlyKeyword", "true")
                .build();

        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .headers(headers)
                .tag(p)
                .build();
        OkHttpUtil.getInstance().enqueue(request, this);
    }

    @Override
    public JSONArray provideCategory() {
        JSONArray list = new JSONArray();
        list.add(new Category("4-1", "易阅通"));
        list.add(new Category("4-0", "易阅通其他类别"));
        return list;
    }

    private void parse(String json, Result result) throws ParseException {

        JSONObject object = JSONObject.parseObject(json);
        int total = object.getIntValue("numberFound");
        int number = object.getIntValue("perPageRows");

        Result.Header header = new Result.Header();
        header.engine = Engine.ID_E4;
        header.engineName = "易阅通";
        header.maxPage = number;
        header.totalCount = total;
        result.headers = new HashSet<>();
        result.headers.add(header);

        JSONArray jsonArray = object.getJSONArray("records");
        List<Search> list = new ArrayList<>();
        Document document;
        for (Object o : jsonArray) {
            Search tto = Search.newInstance(Engine.ID_E4);
            JSONObject obj = (JSONObject) o;
            tto.setAuthor(obj.getString("contentAuthor"));
            document = Jsoup.parse(obj.getString("contentTitle"));
            tto.setName(document.text());
            tto.setSource(obj.getString("publisherName"));
            tto.setCategory("4-1");
            tto.setUrl(href.concat(obj.getString("contentId")));
            tto.setPublishDate(obj.getString("PubYear"));
            list.add(tto);
        }
        result.list = list;
        if (callback != null) callback.callback(result);
    }

    @Override
    public void onFailure(@NotNull Call call, @NotNull IOException e) {
        System.out.println("E4响应失败");
    }

    @Override
    public void onResponse(@NotNull Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
            ResponseBody responseBody = response.body();
            if (responseBody != null) {
                String json = responseBody.string();
                System.out.println(json);
                Param p = (Param) call.request().tag();
                if (p != null) System.out.println("E4响应成功:" + (System.currentTimeMillis() - p.duration) + "ms");
                Result result = new Result(p);
                try {
                    parse(json, result);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static final class Holder {
        private static final AbstractE ins = new E4();
    }

    private E4() {

    }

    public static AbstractE getInstance() {
        return Holder.ins;
    }
}
